﻿using Mapster;
using Service.Auth.Api.Application.Command;
using Service.Auth.Domain.AggregatesModel;
using Service.Auth.Model.Model.Dto;
using Service.Core.Identity;
using Service.Core.Identity.Model;
using Service.Core.Redis.Aop.Cache;
using Service.Core.Repository;
using Service.Framework;
using SqlSugar;

namespace Service.Auth.Api.Application.Query;

/// <summary>
/// 角色菜单查询器
/// </summary>
/// <param name="rolePermissionRepository"></param>
/// <param name="moduleQuery"></param>
public class RolePemissionsQueryService(
    IRepository<RolePermission> rolePermissionRepository
) : IScopedService
{
    [RedisCacheInterceptor(cacheDuration: 0, cacheKey: DefaultRedisKeys.PermissionKey)] //AOP缓存,虚方法

    public virtual async Task<List<PermissionItem>> QueryRolePemissionItemCache()
    {
        return await QueryRolePemissionItem();
    }

    public async Task<List<PermissionItem>> QueryRolePemissionItem()
    {
        //获取所有modulues
        //var modules = await moduleQuery.QueryModulesList();
        var rolePermissions = await rolePermissionRepository.Db.Queryable<RolePermission, Role, Permission>
            ((rp, r, p) =>
                new JoinQueryInfos(JoinType.Left, rp.RoleId == r.Id, JoinType.Left, rp.PermissionId == p.Id))
            .Where((rp, r, p) => !SqlFunc.IsNullOrEmpty(p.ModuleUrl)).Select((rp, r, p) => new RolePermissionDto
            {
                RoleNum = r.RoleNum,
                Name = p.Name,
                ModuleUrl = p.ModuleUrl,
            }).ToListAsync();

        return rolePermissions.Where(s => !string.IsNullOrWhiteSpace(s.ModuleUrl)).SelectMany(s =>
              s.ModuleUrl.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
              .Select(url => new PermissionItem
              {
                  Role = s.RoleNum,
                  Url = url.Trim() // 去除可能存在的多余空格
              })).ToList();
    }

    public virtual async Task<List<PermissionDto>> QueryRolePemissionByRoles(List<long> roleIds)
    {
        var permissionIds = rolePermissionRepository.Db.Queryable<RolePermission>()
            .Where(s => roleIds.Contains(s.RoleId)).Distinct().Select(s => s.PermissionId).ToList();
        var permission = await rolePermissionRepository.Db.Queryable<Permission>()
            .Where(s => permissionIds.Contains(s.Id) && !s.IsButton)
            .OrderBy(s => s.OrderSort)
            .Select(s => new Permission()
            {
                Permissions = SqlFunc.Subqueryable<Permission>()
                .Where(p => p.ParentId == s.Id && p.IsButton).ToList(p => p.Code)
            }, true)
            .ToTreeAsync(s => s.Children, s => s.ParentId, 0);
        return permission.Adapt<List<PermissionDto>>();
    }
}